using Viyi.Util.Extensions.Convert;
using Xunit;

// ReSharper disable TryCastAlwaysSucceeds
// ReSharper disable RedundantCast
// ReSharper disable RedundantTypeArgumentsOfMethod

namespace Viyi.Util.Test.Utils;

public class TestObjectUtil {
    [Fact(DisplayName = "允许值类型AS")]
    public void TestAsStruct() {
        Assert.Equal((short) 123, ((object) (short) 123).As<short>(0));
        Assert.Equal("hello", ((object) "hello").As<string>(string.Empty));
    }

    [Fact(DisplayName = "As失败返回默认值")]
    public void TestInvalidCast() {
        Assert.Equal(-1, ((object) 123L).As<int>(-1));
        Assert.Equal(-2L, ((object) 1234).As<long>(-2L));
        Assert.Null(new object().As<string>());
    }

    [Fact(DisplayName = "对类类型AS()应该和as操作符结果相同")]
    public void TestClassCast() {
        Sub sub = new Sub();
        Super super = sub;
        Super super2 = new Super();

        Assert.Equal(sub as Super, sub.As<Super>());
        Assert.Equal(super as Sub, super.As<Sub>());
        Assert.Equal(super2 as Sub, super2.As<Sub>());
    }

    private class Super { }
    private sealed class Sub : Super { }

    // 由于是直接封装的 Convert.ChangeType，所以成功的情况不用测试
    [Fact(DisplayName = "Convert To 失败返回默认值")]
    public void ConvertFail() {
        Assert.Equal(DateTime.MinValue, ObjectToStructExtensions.ConvertTo<DateTime>("abcdef"));
    }

    [Fact(DisplayName = "ObjectUtil.ToInt32为代表测试ToXxxx")]
    public void ConvertInt32() {
        Assert.Equal(4567, ObjectToStructExtensions.ConvertTo<int>(4567L));
        Assert.Equal(1579, ObjectToStructExtensions.ConvertTo<int>("1579"));
        Assert.Equal(0, ObjectToStructExtensions.ConvertTo<int>("xyz"));
        Assert.Equal(-3, ObjectToStructExtensions.ConvertTo<int>("xyz", -3));
    }
}
